package cn.org.xiaosheng.jdk11;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author XiaoSheng
 * @date 2024/8/7 下午1:05
 */
public class Features {

    public Features() throws IOException, InterruptedException {
    }

    public static void main(String[] args) throws IOException {
        // 局部变量类型推断就是左边的类型直接使用 var 定义
        // 而不用写具体的类型，编译器能根据右边的表达式自动推断类型
        var javastack = "javastack";
        System.out.println(javastack);

        /**
         * 字符串增强
         */
        //判断字符串是否为空白

        "".isBlank();//true

        //去除首尾空格

        " Javastack ".strip();//"Javastack"

        //去除尾部空格

        "Javastack ".stripTrailing();//"Javastack"

        //去除首部空格

        " Javastack".stripLeading();//"Javastack"

        //复制字符串

        "Java".repeat(3);//"JavaJavaJava"

        //行数统计
        "A\nB\nC".lines().count();//3


        /**
         * 集合增强
         */
        var list = List.of("Java", "Python", "C");

        var copy = List.copyOf(list);

        System.out.println(list == copy);   // true

        var list1 = new ArrayList<String>();

        var copy1 = List.copyOf(list);

        System.out.println(list1 == copy1);   // false
        /**
         * static<E>List<E> of(E...elements){
         *
         * switch(elements.length){//implicitnullcheckofelements
         *
         * case0:
         *
         * returnImmutableCollections.emptyList();
         *
         * case1:
         *
         * returnnewImmutableCollections.List12<>(elements[0]);
         *
         * case2:
         *
         * returnnewImmutableCollections.List12<>(elements[0],elements[1]);
         *
         * default:
         *
         * returnnewImmutableCollections.ListN<>(elements);
         *
         * }
         *
         * }
         *
         * static<E>List<E>copyOf(Collection<?extendsE>coll){
         *
         * returnImmutableCollections.listCopy(coll);
         *
         * }
         *
         * static<E>List<E>listCopy(Collection<?extendsE>coll){
         *
         * if(collinstanceofAbstractImmutableList&&coll.getClass()!=SubList.class){
         *
         * return(List<E>)coll;
         *
         * }else{
         *
         * return(List<E>)List.of(coll.toArray());
         *
         * }
         *
         * }
         *
             可以看出 copyOf 方法会先判断来源集合是不是 AbstractImmutableList 类型的，如果是，就直接返回，如果不是，则调用 of 创建一个新的集合。
             示例2因为用的 new 创建的集合，不属于不可变 AbstractImmutableList 类的子类，所以 copyOf 方法又创建了一个新的实例，所以为false.
             注意：使用of和copyOf创建的集合为不可变集合，不能进行添加、删除、替换、排序等操作，不然会报java.lang.UnsupportedOperationException异常。
             上面演示了 List 的 of 和 copyOf 方法，Set 和 Map 接口都有。
         */

        /**
         * Stream加强
         */
       // Stream 是 Java 8 中的新特性，Java 9 开始对 Stream 增加了以下 4 个新方法。

       // 增加单个参数构造方法，可为null
        // 代码解读复制代码Stream.ofNullable(null).count();//0

       // 增加 takeWhile 和 dropWhile 方法

        Stream.of(1,2,3,2,1)

                .takeWhile(n->n<3)

                .collect(Collectors.toList());//[1,2]
        // 从开始计算，当 n < 3 时就截止。

        Stream.of(1,2,3,2,1)

                .dropWhile(n->n<3)

                .collect(Collectors.toList());//[3,2,1]
        // 这个和上面的相反，一旦 n < 3 不成立就开始计算。

        /**
         * Optional加强
         * Opthonal 也增加了几个非常酷的方法，现在可以很方便的将一个 Optional 转换成一个 Stream
         * 或者当一个空 Optional 时给它一个替代的。
         */
        String javastack2 = Optional.of("javastack").orElseThrow();//javastack
        System.out.println(javastack2);

        long javastack1 = Optional.of("javastack").stream().count();//1
        System.out.println(javastack1);

        Optional.ofNullable(null)

                    .or(()->Optional.of("javastack"))

                    .get();//javastack


        /**
         * Input加强
         * InputStream 终于有了一个非常有用的方法：transferTo，
         * 可以用来将数据直接传输到 OutputStream，这是在处理原始数据流时非常常见的一种用法，如下示例。
         */
        var classLoader=ClassLoader.getSystemClassLoader();

        var inputStream=classLoader.getResourceAsStream("javastack.txt");

        var javastack3 = File.createTempFile("javastack2","txt");

        try(var outputStream = new FileOutputStream(javastack3)){

            inputStream.transferTo(outputStream);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * Http Client
     * 这是 Java 9 开始引入的一个处理 HTTP 请求的的孵化 HTTP Client API，
     * 该 API 支持同步和异步，而在 Java 11 中已经为正式可用状态，
     * 你可以在 java.net 包中找到这个 API。
     */
//    HttpRequest request= HttpRequest.newBuilder()
//
//            .uri(URI.create("https://javastack.cn"))
//
//            .GET()
//
//            .build();
//
//    HttpClient client= HttpClient.newHttpClient();
//
//        //同步
//
//    HttpResponse<String> response = client.send(request,HttpResponse.BodyHandlers.ofString());
//
//            System.out.println(response.);
//
//            //异步
//
//            client.sendAsync(request,HttpResponse.BodyHandlers.ofString())
//
//            .thenApply(HttpResponse::body)
//
//            .thenAccept(System.out::println);



}
